{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Feature Layer properties\n",
    "\n",
    "Hosted Feature services, also called hosted feature layers, can contain one or more feature layers with spatial information, or one or more tables that do not have spatial information. They also contain many properties that inform client applications about their state, version, capabilities, extent, allowed operations and much more. Together these properties make up a service or layer `definition`. Refer to the [feature service](/rest/services-reference/enterprise/feature-service/) page to learn about these types of services in detail. This guide outlines how you can query and update feature service properties using the item sourced by this feature service.\n",
    "\n",
    "> **NOTE:** You must be the item owner, an organization administrator, or an user assigned a role with the appropriate privileges to run the `update_definition()` method used in this guide."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Connect to a Web GIS and retrieve a Feature Layer item"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [],
   "source": [
    "# connect to your GIS with publisher or higher privileges\n",
    "from arcgis.gis import GIS\n",
    "gis = GIS(profile='layer_owner')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div class=\"item_container\" style=\"height: auto; overflow: hidden; border: 1px solid #cfcfcf; border-radius: 2px; background: #f6fafa; line-height: 1.21429em; padding: 10px;\">\n",
       "                    <div class=\"item_left\" style=\"width: 210px; float: left;\">\n",
       "                       <a href='https://geosaurus.maps.arcgis.com/home/item.html?id=e0dae2efe40a414a9700bee3a35c846b' target='_blank'>\n",
       "                        <img src='' width='200' height='133' class=\"itemThumbnail\">\n",
       "                       </a>\n",
       "                    </div>\n",
       "\n",
       "                    <div class=\"item_right\"     style=\"float: none; width: auto; overflow: hidden;\">\n",
       "                        <a href='https://geosaurus.maps.arcgis.com/home/item.html?id=e0dae2efe40a414a9700bee3a35c846b' target='_blank'><b>Ports along the US West Coast</b>\n",
       "                        </a>\n",
       "                        <br/>Locations of various ports along the West Coast of the United States.<img src='https://geosaurus.maps.arcgis.com/home/js/jsapi/esri/css/images/item_type_icons/featureshosted16.png' style=\"vertical-align:middle;\" width=16 height=16>Feature Layer Collection by api_data_owner\n",
       "                        <br/>Last Modified: July 18, 2023\n",
       "                        <br/>0 comments, 3 views\n",
       "                    </div>\n",
       "                </div>\n",
       "                "
      ],
      "text/plain": [
       "<Item title:\"Ports along the US West Coast\" type:Feature Layer Collection owner:api_data_owner>"
      ]
     },
     "execution_count": 21,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "search_result= gis.content.search(\"Ports along west coast\", \"Feature Layer\")\n",
    "ports_item = search_result[0]\n",
    "ports_item"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## The feature service definition\n",
    "Once you have a `Feature Layer` item, you can access the definition of the feature service that sources the item.  First, import the [`FeatureLayerCollection`](/python/api-reference/arcgis.features.toc.html#featurelayercollection) class. This class contains a method called [`fromitem()`](/python/latest/api-reference/arcgis.features.toc.html#arcgis.features.FeatureLayerCollection.fromitem), which returns an instance of a `FeatureLayerCollection` object. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [],
   "source": [
    "from arcgis.features import FeatureLayerCollection\n",
    "ports_flc = FeatureLayerCollection.fromitem(ports_item)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Querying the `properties` property on this `FeatureLayerCollection` object returns a dictionary of all the feature service properties. Let's inspect if the `description` or `copyright` attributes of the service have been entered."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{\n",
       "  \"currentVersion\": 11.1,\n",
       "  \"serviceItemId\": \"e0dae2efe40a414a9700bee3a35c846b\",\n",
       "  \"serviceDescription\": \"\",\n",
       "  \"hasVersionedData\": false,\n",
       "  \"supportsDisconnectedEditing\": false,\n",
       "  \"hasStaticData\": false,\n",
       "  \"hasSharedDomains\": false,\n",
       "  \"maxRecordCount\": 1000,\n",
       "  \"supportedQueryFormats\": \"JSON\",\n",
       "  \"supportsVCSProjection\": false,\n",
       "  \"supportedExportFormats\": \"csv,shapefile,sqlite,geoPackage,filegdb,featureCollection,geojson,excel\",\n",
       "  \"capabilities\": \"Create,Delete,Query,Update,Editing,Sync\",\n",
       "  \"description\": \"\",\n",
       "  \"copyrightText\": \"\",\n",
       "  \"spatialReference\": {\n",
       "    \"wkid\": 102100,\n",
       "    \"latestWkid\": 3857\n",
       "  },\n",
       "  \"initialExtent\": {\n",
       "    \"xmin\": -17764735.368653413,\n",
       "    \"ymin\": 2241467.1730974796,\n",
       "    \"xmax\": -13044788.959018612,\n",
       "    \"ymax\": 5721784.0173567245,\n",
       "    \"spatialReference\": {\n",
       "      \"wkid\": 102100,\n",
       "      \"latestWkid\": 3857\n",
       "    }\n",
       "  },\n",
       "  \"fullExtent\": {\n",
       "    \"xmin\": -17764735.368653413,\n",
       "    \"ymin\": 2241467.1730974796,\n",
       "    \"xmax\": -13044788.959018612,\n",
       "    \"ymax\": 5721784.0173567245,\n",
       "    \"spatialReference\": {\n",
       "      \"wkid\": 102100,\n",
       "      \"latestWkid\": 3857\n",
       "    }\n",
       "  },\n",
       "  \"allowGeometryUpdates\": true,\n",
       "  \"units\": \"esriMeters\",\n",
       "  \"supportsAppend\": true,\n",
       "  \"supportsSharedDomains\": true,\n",
       "  \"supportsWebHooks\": true,\n",
       "  \"supportsTemporalLayers\": true,\n",
       "  \"layerOverridesEnabled\": true,\n",
       "  \"size\": 32768,\n",
       "  \"syncEnabled\": true,\n",
       "  \"syncCapabilities\": {\n",
       "    \"supportsAsync\": true,\n",
       "    \"supportsRegisteringExistingData\": true,\n",
       "    \"supportsSyncDirectionControl\": true,\n",
       "    \"supportsPerLayerSync\": true,\n",
       "    \"supportsPerReplicaSync\": true,\n",
       "    \"supportsSyncModelNone\": true,\n",
       "    \"supportsRollbackOnFailure\": true,\n",
       "    \"supportsAttachmentsSyncDirection\": true,\n",
       "    \"supportsBiDirectionalSyncForServer\": true,\n",
       "    \"supportedSyncDataOptions\": 4\n",
       "  },\n",
       "  \"supportsApplyEditsWithGlobalIds\": true,\n",
       "  \"supportsReturnDeleteResults\": true,\n",
       "  \"supportsLayerOverrides\": true,\n",
       "  \"supportsTilesAndBasicQueriesMode\": true,\n",
       "  \"supportsQueryContingentValues\": true,\n",
       "  \"supportedContingentValuesFormats\": \"JSON, PBF\",\n",
       "  \"supportsContingentValuesJson\": 2,\n",
       "  \"advancedEditingCapabilities\": {\n",
       "    \"supportsSplit\": false,\n",
       "    \"supportsReturnServiceEditsInSourceSR\": false,\n",
       "    \"supportsAsyncApplyEdits\": true,\n",
       "    \"supportsReturnEditResults\": true,\n",
       "    \"supportsApplyEditsbyUploadID\": true,\n",
       "    \"supportedApplyEditsUploadIDFormats\": \"JSON\"\n",
       "  },\n",
       "  \"editorTrackingInfo\": {\n",
       "    \"enableEditorTracking\": false,\n",
       "    \"enableOwnershipAccessControl\": false,\n",
       "    \"allowOthersToQuery\": true,\n",
       "    \"allowOthersToUpdate\": true,\n",
       "    \"allowOthersToDelete\": true,\n",
       "    \"allowAnonymousToQuery\": true,\n",
       "    \"allowAnonymousToUpdate\": true,\n",
       "    \"allowAnonymousToDelete\": true\n",
       "  },\n",
       "  \"xssPreventionInfo\": {\n",
       "    \"xssPreventionEnabled\": true,\n",
       "    \"xssPreventionRule\": \"InputOnly\",\n",
       "    \"xssInputRule\": \"rejectInvalid\"\n",
       "  },\n",
       "  \"layers\": [\n",
       "    {\n",
       "      \"id\": 0,\n",
       "      \"name\": \"Ports_along_the_US_West_Coast\",\n",
       "      \"parentLayerId\": -1,\n",
       "      \"defaultVisibility\": true,\n",
       "      \"subLayerIds\": null,\n",
       "      \"minScale\": 73957191,\n",
       "      \"maxScale\": 0,\n",
       "      \"type\": \"Feature Layer\",\n",
       "      \"geometryType\": \"esriGeometryPoint\"\n",
       "    }\n",
       "  ],\n",
       "  \"tables\": []\n",
       "}"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "ports_flc.properties"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Both properties are empty. Let's update them as an example of how to update feature service properties"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Update the feature service definition"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The [`manager`](/python/api-reference/arcgis.features.toc.html#arcgis.features.FeatureLayerCollection.manager) property accesses the [`FeatureLayerCollectionManager`](/python/api-reference/arcgis.features.managers.html#featurelayercollectionmanager) class. Use the [`update_definition()`](/python/api-reference/arcgis.features.toc.html#arcgis.features.FeatureLayerCollection.update_definition) method and pass in a dictionary of the properties you want to edit to update the definition of the hosted feature service."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Updating feature service properties"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'success': True}"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "update_dict = {'description':'Updated using ArcGIS Python API',\n",
    "              'copyrightText':'copyright Python API guide'}\n",
    "ports_flc.manager.update_definition(update_dict)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Let us access the service definition once again to see if these fields are updated"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'Updated using ArcGIS Python API'"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "ports_flc.properties.description"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'copyright Python API guide'"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "ports_flc.properties.copyrightText"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Updating feature service capabilities\n",
    "\n",
    "Let's edit the `capabilities` property to disable `editing` and `sync`"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'success': True}"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "update_dict2 = {\"capabilities\": \"Query\",\n",
    "               \"syncEnabled\": False}\n",
    "ports_flc.manager.update_definition(update_dict2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'Query'"
      ]
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "ports_flc.properties.capabilities"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "False"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "ports_flc.properties.syncEnabled"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "False"
      ]
     },
     "execution_count": 18,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "\"syncCapabilities\" in ports_flc.properties"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Turning off `syncEnabled` automatically removes `syncCapabilities`."
   ]
  }
 ],
 "metadata": {
  "anaconda-cloud": {},
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.11.0"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
